﻿namespace com.savealot.SharePoint
{
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Text;

    using com.savealot.Extensions.StringExtensions;

    using Microsoft.SharePoint;

    /// <summary> 
    /// This class is a serializable equivalent of SPFieldLookupValue. 
    /// </summary> 
    [Serializable]
    public class SPLookupValue
    {
        #region Fields

        const string delimiter = ";#";

        static SPLookupValue _Empty;

        #endregion Fields

        #region Constructors

        public SPLookupValue( string value )
        {
            process( value );
        }

        public SPLookupValue( int lookupId, string lookupValue )
        {
            LookupId = lookupId;
            LookupValue = lookupValue;
        }

        public SPLookupValue( SPFieldLookupValue value )
        {
            LookupId = value.LookupId;
            LookupValue = value.LookupValue;
        }

        internal SPLookupValue( )
        {
        }

        #endregion Constructors

        #region Properties

        public static SPLookupValue Empty
        {
            get
            {
                if ( _Empty == null )
                    _Empty = new SPLookupValue( 0, null );
                return _Empty;
            }
        }

        public int LookupId
        {
            get;
            set;
        }

        public string LookupValue
        {
            get;
            set;
        }

        internal static string[] Delimiter
        {
            get
            {
                return new string[ ] { delimiter };
            }
        }

        #endregion Properties

        #region Methods

        /// <summary> 
        /// Return true if the specified SPLookupValue is null, or if the LookupId is equal to 0 and the LookupValue is empty or null; otherwise return false. 
        /// </summary> 
        /// <param name="value"></param> 
        /// <returns></returns> 
        public static bool IsNullOrEmpty( SPLookupValue value )
        {
            if ( value == null )
                return true;
            if ( value.LookupId == Empty.LookupId && (
                value.LookupValue == Empty.LookupValue || string.IsNullOrEmpty( value.LookupValue ) ) )
                return true;
            return false;
        }

        /// <summary> 
        /// Convert the value of this instance to an instance of type SPFieldLookupValue. 
        /// </summary> 
        /// <returns></returns> 
        public SPFieldLookupValue ToSPFieldLookupValue( )
        {
            return new SPFieldLookupValue( LookupId, LookupValue );
        }

        public override string ToString( )
        {
            return LookupValue;
        }

        void process( string value )
        {
            if ( !string.IsNullOrEmpty( value ) )
            {
                string[ ] s = value.Split( Delimiter, StringSplitOptions.None );
                if ( s.Length > 0 )
                {
                    int? n = s[ 0 ].ToNullableInt32( );
                    if ( n.HasValue )
                        LookupId = n.Value;
                    else
                        LookupId = Int32.MinValue;
                    if ( s.Length > 1 )
                    {
                        LookupValue = s[ 1 ];
                        if ( s.Length > 2 )
                        {
                            StringBuilder sb = new StringBuilder( LookupValue );
                            int i = 2;
                            while ( i < s.Length )
                            {
                                sb.AppendFormat( "{0}{1}", delimiter, s[ i ] );
                                i++;
                            }
                            LookupValue = sb.ToString( );
                            sb = null;
                        }
                    }
                }
            }
        }

        #endregion Methods
    }

    public class SPLookValueCollection : ReadOnlyCollection<SPLookupValue>
    {
        #region Constructors

        public SPLookValueCollection( SPFieldLookupValueCollection value )
            : base(process( value ))
        {
        }

        #endregion Constructors

        #region Methods

        /// <summary>
        /// Returns a <see cref="System.String"/> that represents this instance.
        /// </summary>
        /// <returns>
        /// A <see cref="System.String"/> that represents this instance.
        /// </returns>
        public override string ToString( )
        {
            return string.Format( "Count = {0}", base.Count );
        }

        /// <summary>
        /// Processes the specified value.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        static IList<SPLookupValue> process( SPFieldLookupValueCollection value )
        {
            List<SPLookupValue> list = new List<SPLookupValue>( );
            if ( value != null && value.Count > 0 )
            {
                foreach ( SPFieldLookupValue v in value )
                {
                    list.Add( new SPLookupValue( v.LookupId, v.LookupValue ) );
                }
            }
            return list;
        }

        #endregion Methods
    }
}